#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>


#define TASK_NUM 5
typedef void(*task)();
///////////////////////////////////////////////////////////////////////////
void download()
{
    printf("This download task is running!\n");
}

void writelog()
{
    printf("This write log task is running!\n");
}

void printinfo()
{
    printf("This print info task is running!\n");
}
///////////////////////////////////////////////////////////////////////////
       
void Init(task tasks[], int num)
{
    for(int i = 0; i < num; i++)
    {
        tasks[i] = NULL;
    }
}

int taskadd(task tasks[], task t)
{
    for(int i = 0; i < TASK_NUM; i++)
    {
        if(tasks[i] == NULL)
        {
            tasks[i] = t;
            return 1;//增加任务成功
        }
    }
    return 0;//增加任务失败
}

void executeTask(task tasks[], int num)
{
    for(int i = 0; i < num; i++)
    {
        tasks[i]();
    }
}
///////////////////////////////////////////////////////////////////////////////////////
void worker(int cnt)
{
    printf("I am child, pid:%d, cnt:%d\n", getpid(), cnt);
}

int main()
{
    task tasks[TASK_NUM];
    Init(tasks, TASK_NUM);
    taskadd(tasks, download); 
    taskadd(tasks, writelog); 
    taskadd(tasks, printinfo); 

    pid_t id = fork();
    if(id == 0)
    {//child
         int cnt = 5;
         while(cnt)
         {
             worker(cnt--);
             sleep(1);
         }
         exit(3);
    }

    //parent
    while(1)
    {
         int status = 0;
         pid_t rid = waitpid(id, &status, WNOHANG);
         if(rid > 0)
         {
              printf("wait sucess!\n, pid:%d, rid:%d, exit code:%d, signal:%d\n",getpid(), rid, (status>>8)&0xFF, status&0x7F);
              break;
         }
         else if(rid == 0)
         {//wait sucess, but child not quit
             printf("------------------------------------------------\n");
             printf("wait sucess, but chils alive, wait again!\n");
             executeTask(tasks, 3);
             printf("------------------------------------------------\n");
         }
         else{
             printf("wait failed!\n");
             break;
         }
         sleep(1);
    }
    return 0;
}




//const int n = 10;
//
//void worker(int number)
//{
//    int cnt = 5;
//    while(cnt)
//    {
//        printf("I am child, pid:%d, ppid:%d, numb:%d, cnt:%d\n", getpid(), getppid(), number, cnt--);
//        sleep(1);
//    }
//}
//
//int main()
//{
//    int status = 0;
//    for(int i = 0; i < n; i++)
//    {
//        pid_t id =fork();
//        if(id == 0)
//        {
//            worker(i);
//            exit(i);
//        }
//    }
//
//    for(int i = 0; i < n; i++)
//    {
//        pid_t rid = waitpid(-1, NULL, 0);
//        printf("I am parent, pid:%d, rid:%d, status:%d, exit code:%d\n", getpid(), rid, status, WEXITSTATUS(status));
//    }
//    return 0;
//}



//int main()
//{
//    int status = 0;
//    pid_t id = fork();
//    if(id == 0)
//    {
//        int cnt = 3;
//        while(cnt)
//        {
//            printf("I am child, cnt:%d\n", cnt--);
//            sleep(1);
//        }
//        exit(3);
//    }
//    else if(id > 0)
//    {
//        pid_t rid = waitpid(id, &status, 0);//以阻塞方式等待
//        if(WIFEXITED(status))
//        {
//            //printf("I am parent, pid:%d, rid:%d, status:%d, exit code:%d, signal:%d\n", getpid(), rid, status, (status>>8)&0xFF, status&0x7F);
//            printf("I am parent, pid:%d, rid:%d, status:%d, exit code:%d\n", getpid(), rid, status, WEXITSTATUS(status));
//        }
//    }
//    return 0;
//}



//void worker()
//{
//    int cnt = 5;
//    while(cnt)
//    {
//        printf("I am child process, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt--);
//        sleep(1);
//    }
//}
//
//int main()
//{
//    pid_t id = fork();
//    pid_t testid = waitpid(11, NULL, 0);//指定进程不存在，返回对于的错误码
//    printf("testid: %d\n", testid);
//    if(id == 0)
//    {
//        //child
//        worker();
//        exit(0);
//    }
//    else{
//        //parent
//        sleep(10);
//        pid_t rid = wait(NULL);
//        if(rid == id)
//        {
//            printf("child process being recyceled sucess!, pid:%d, rid:%d\n", getpid(), rid);
//        }
//        sleep(3);
//    }
//    return 0;
//}
